/**

program : To calculate eigen values using power method
              It is the approximate method for calculating eigen values
	 For calculating 
	     max eigen value 
             x0=sumation(alpha(i)U(i))     where i<=n
	     Ax0=sumation(alpha(i)lamda(i)U(i))      where i<=n  
	        
 

@author vishwajeet dusane 
*/

#include"LuDeco.h"

class PowerMethod:public LUDecomposition
{

 public:
Matrix A,X;
  double max,prevMax,tol;
  PowerMethod();
 // find largest eigen value
  int findMaxEigenValue(char [50],char [50]);
 
 //return max element from matrix 
  double getMax(Matrix);
  
 //find small eigen  value
   int findMinEigenValue(char [50],char [50]);
 
 //find reamining
  //eigen value
 
 
  //initial X0

};


PowerMethod::PowerMethod()
{
 }
 
 

int PowerMethod:: findMinEigenValue(char fnameA[50],char fnameX[50])
{

LUDecomposition A;
int iteration;
iteration=0; 

     //A.readMatrix(fnameA);
     
 
 // check 4 diagonally dominant
 
     if(!A.isDiagonallyDominant())
       {
       cout<<"Making Matrix Diagonally dominant"<<endl;
         for(int i=0;i<A.row;i++)
	    if(!A.isDiagonallyDominant(i)) 
	      A.makeDiagonallyDominant(i); 
       } 
    
      prevMax=242; 
      A.luDeco(fnameA,fnameX);
      
   while(1)
   {     
     A.findRoots();
     iteration++;     
      max=getMax(A.Xn);
       
      A.Xn=A.Xn/max;
      
       A.B=A.Xn;
        
  //  A.Xn.printMatrix("matrix After division");
 
 //isTolerable
   tol=mod(prevMax-max);
//   cout<<"Tol="<<tol<<endl;  
    if(tol<0.0000001)
      break;
     prevMax=max;
      
    }    

cout<<"Min Eigen Value is  "<<max<<"And Number Of iterations :"<<iteration<<endl;

} 

//----------------------------------------------------------------------------------------------

int PowerMethod:: findMaxEigenValue(char fnameA[50],char fnameX[50])
{
  
  int iteration;
  iteration=0;
A.readMatrix(fnameA);
     X.readMatrix(fnameX);
  
 // check 4 diagonally dominant
 
     if(!A.isDiagonallyDominant())
       {
       cout<<"Making Matrix Diagonally dominant"<<endl;
         for(int i=0;i<A.row;i++)
	    if(!A.isDiagonallyDominant(i)) 

	     A.makeDiagonallyDominant(i); 
      } 
         
       
 
 // get initial X   
 
  
  prevMax=12312313;
while(1)
{
  //calculate AX
   X=A*X;
   iteration++;
   
   //X.printMatrix("matrix After multiplication");
  //get MAX from it
    max=getMax(X);
    
  //cout<<"max="<<max<<endl;  
  //divide by max
      X=X/max;
//    X.printMatrix("matrix After division");
 //isTolerable
   tol=mod(prevMax-max);
  // cout<<"Tol="<<tol<<endl;  
    if(tol<0.0000001)
      break;
     prevMax=max;
 }   
 
 
// X.printMatrix("X matrix");
 cout<<"Max Eigen Value is  "<<max<<"Number Of itearation ="<<iteration<<endl;
 
}


double PowerMethod::getMax(Matrix X)
{
   double max;
   max=0;
    for(int i=0;i<X.row;i++)
    {
      for(int j=0;j<X.column;j++)
      {
        if(X.matrix[i][j]>max) 
	  max=X.matrix[i][j];
      }  
    }
   
 return max;
}

